package com.huilian.iotbox.admin.controller;

import com.alibaba.druid.util.StringUtils;
import com.aliyuncs.exceptions.ClientException;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.admin.service.AgencyService;
import com.huilian.iotbox.admin.service.DeviceService;
import com.huilian.iotbox.admin.service.UserService;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.controller.BaseController;
import com.huilian.iotbox.data.dto.AppFileDto;
import com.huilian.iotbox.data.dto.DeviceDto;
import com.huilian.iotbox.data.dto.RemoteWriteDeivceNoDto;
import com.huilian.iotbox.data.enums.LogManipulateTypeEnum;
import com.huilian.iotbox.data.enums.OperationLogEnum;
import com.huilian.iotbox.data.enums.RoleEnum;
import com.huilian.iotbox.data.po.Agency;
import com.huilian.iotbox.data.service.ErrorLogCommonService;
import com.huilian.iotbox.data.service.LogManipulateService;
import com.huilian.iotbox.data.utils.Util;
import com.huilian.iotbox.data.vo.DeviceVo;
import com.huilian.iotbox.data.vo.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 谢洛涛
 * @date 2021/3/31 12:02
 */
@RestController
@RequestMapping("/api/device")
public class DeviceController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(DeviceController.class);
    @Autowired
    private UserService userService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private AgencyService agencyService;
    @Autowired
    private LogManipulateService logManipulateService;
    @Autowired
    private ErrorLogCommonService errorLogCommonService;
    @Autowired
    private RedisTemplate<String, Serializable> redisCacheTemplate;

    /**
     * 烧录设备软件请求获取设备号、密码
     *
     * @param deviceDto
     * @return
     */
    @GetMapping("/getDeviceInfoFromBurningSoftware")
    public ServerResponse getDeviceInfoFromBurningSoftware(DeviceDto deviceDto) throws IOException, NoSuchAlgorithmException {
        return deviceService.getDeviceInfoFromBurningSoftware(deviceDto);
    }

    /**
     * 获取设备二维码
     *
     * @param request
     * @param deviceDto
     * @return
     * @throws Exception
     */
    @PostMapping("/getDeviceQrCode")
    public ServerResponse getDeviceQrCode(HttpServletRequest request, @RequestBody DeviceDto deviceDto) throws Exception {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        return deviceService.getDeviceQrCode(deviceDto);
    }

    @PostMapping("/batchUpdateStatus")
    public ServerResponse batchUpdateStatus(HttpServletRequest request, @RequestBody DeviceDto deviceDto) throws Exception {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        return deviceService.batchUpdateStatus(deviceDto);
    }

    /**
     * 兑币机APK根据合作伙伴号自动分配设备号
     *
     * @param request
     * @param deviceDto
     * @return
     */
    @PostMapping("/v1/registerDeviceByAgencyNo")
    public ServerResponse registerDeviceByAgencyNo(@RequestBody DeviceDto deviceDto) throws Exception {
        return deviceService.registerDeviceByAgencyNo(deviceDto);
    }

    /**
     * 售货机根据agencyNo分配设备号                          <br/>
     * <br/>
     * 需要参数                                  <br/>
     * agencyNo                                 <br/>
     * cpuId                                    <br/>
     * timestamp                                <br/>
     * deviceRegisterType                                     <br/>
     * sign                                     <br/>
     *
     * @param deviceDto
     * @return
     */
    @PostMapping("/v2/registerDeviceByAgencyNo")
    public ServerResponse registerDeviceByAgencyNoV2(@RequestBody DeviceDto deviceDto) {
        try {
            return ServerResponse.createBySuccess(deviceService.registerDeviceByAgencyNoV2(deviceDto));
        } catch (Exception e) {
            e.printStackTrace();
            return ServerResponse.createByErrorMessage(e.getMessage());
        }
    }

    /**
     * 兑币机APK根据CPUId查设备-v3
     *
     * @param request
     * @param deviceDto
     * @return
     */
    @PostMapping("/v3/queryByCpuId")
    public ServerResponse queryByCpuIdV3(@RequestBody DeviceDto deviceDto) throws Exception {
        return deviceService.queryByCpuIdV3(deviceDto);
    }

    /**
     * 兑币机APK根据CPUId查设备-v2
     *
     * @param request
     * @param deviceDto
     * @return
     */
    @PostMapping("/v2/queryByCpuId")
    public ServerResponse queryByCpuIdV2(HttpServletRequest request, @RequestBody DeviceDto deviceDto) throws Exception {
        return deviceService.queryByCpuIdV2(deviceDto);
    }

    /**
     * 发送调试协议
     *
     * @param deviceDto
     * @param request
     * @return
     */
    @PostMapping("/sendTestCmd")
    public ServerResponse sendTestCmd(@RequestBody DeviceDto deviceDto, HttpServletRequest request) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        if (!RoleEnum.SUPER_ADMINISTRATOR.getRoleId().equals(userInfo.getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限发送调试协议");
        }
        return deviceService.sendTestCmd(deviceDto);
    }

    @GetMapping("/{id}")
    public ServerResponse findOneDeviceById(HttpServletRequest request, @PathVariable Integer id) {
        DeviceDto deviceDto = new DeviceDto();
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        deviceDto.setId(id);
        return ServerResponse.createBySuccess(deviceService.findOneDeviceById(deviceDto));
    }

    /**
     * 超级兑币机动态注册设备号
     *
     * @param deviceDto
     * @param request
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @PostMapping("/v1/registerDevice")
    public ServerResponse registerDevice(@RequestBody DeviceDto deviceDto, HttpServletRequest request) throws IOException, NoSuchAlgorithmException, ClientException {
        return deviceService.registerDevice(deviceDto, request);
    }

    /**
     * 盒子参数
     */
    @PostMapping("/boxParameters")
    public ServerResponse boxParameters(@RequestBody DeviceDto deviceDto, HttpServletRequest request) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        return deviceService.boxParameters(deviceDto);
    }

    @GetMapping("/findResidueNewDeviceToDay")
    public ServerResponse findResidueNewDeviceToDay(HttpServletRequest request) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        DeviceDto deviceDto = new DeviceDto();
        deviceDto.setUserInfo(userInfo);
        return deviceService.findResidueNewDeviceToDay(deviceDto);
    }

    @PostMapping("/addBatchEstablishNewDevice")
    public ServerResponse addBatchEstablishNewDevice(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
//        return deviceService.addBatchEstablishNewDevice(deviceDto);
        return null;
    }

    /**
     * 解绑设备
     *
     * @param request
     * @param deviceDto
     * @return
     */
    @PutMapping("/unBindingDevice")
    public ServerResponse unBindingDevice(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (RoleEnum.FINANCE.getRoleId().equals(deviceDto.getUserInfo().getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限解绑设备！");
        }
        ServerResponse response = deviceService.unBindingDevice(deviceDto);
        String r1 = StringUtils.isEmpty(deviceDto.getUsername()) ? "" : deviceDto.getUsername();
        String r2 = StringUtils.isEmpty(deviceDto.getName()) ? "" : "(" + deviceDto.getName() + ")";
        String r3 = StringUtils.isEmpty(r1 + r2) ? "" : "的";
        String r4 = StringUtils.isEmpty(deviceDto.getDeviceNo()) ? "" : "(" + deviceDto.getDeviceNo() + ")";
        String remark = "解绑" + r1 + r2 + r3 + "设备" + r4;
        if (OperationLogEnum.STATUS_FAIL.getCode().equals(Util.stringConvert(response.getStatus()))) {
            remark = remark + "失败";
        } else {
            remark = remark + "成功";
        }
        logManipulateService.insert(userInfo, deviceDto.toString(), remark, request, response, deviceDto.getDeviceNo(), LogManipulateTypeEnum.DEVICE_UNBIND.getCode());

        return response;
    }

    @GetMapping("/findDevice/{merchantStoreId}")
    public ServerResponse findDevice(HttpServletRequest request, @PathVariable Integer merchantStoreId) {
        DeviceDto deviceDto = new DeviceDto();
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        deviceDto.setMerchantStoreId(merchantStoreId);
        return ServerResponse.createBySuccess(deviceService.findDevice(deviceDto));
    }


    @PostMapping("/list")
    public ServerResponse findDeviceList(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        deviceDto.setPageNum(Integer.parseInt(request.getParameter("pageNum")));
        deviceDto.setPageSize(Integer.parseInt(request.getParameter("pageSize")));
        return ServerResponse.createBySuccess(deviceService.findDeviceList(deviceDto));
    }

    @PostMapping("/findDeviceStatistic")
    public ServerResponse findDeviceStatistic(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        return ServerResponse.createBySuccess(deviceService.findDeviceStatistic(deviceDto));
    }


    /**
     * 根据设备号范围查询设备，准备分配
     *
     * @param request
     * @param deviceDto
     * @return
     */
    @PostMapping("/findDistributionDevice")
    public ServerResponse findDistributionDevice(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        deviceDto.setPageNum(Integer.parseInt(request.getParameter("pageNum")));
        deviceDto.setPageSize(Integer.parseInt(request.getParameter("pageSize")));
        List<DeviceVo> deviceVoList = deviceService.findDistributionDevice(deviceDto);
        if (deviceVoList.size() > 0) {
            PageInfo pageInfo = new PageInfo(deviceVoList);
            return ServerResponse.createBySuccess(pageInfo);
        } else {
            return ServerResponse.createByErrorMessage("没有查询到指定的设备，请检查设备号区间是否正确");
        }
    }

    @PutMapping("/distributionDevice")
    public ServerResponse distributionDevice(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (RoleEnum.FINANCE.getRoleId().equals(deviceDto.getUserInfo().getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限分配设备！");
        }
        ServerResponse response = deviceService.distributionDevice(deviceDto);
        Agency agency = agencyService.findOneAgencyById(deviceDto.getAgencyId());
        String remark = "";
        if (deviceDto.getIsAnew() == 0) {
            remark = "新分配";
        } else {
            remark = "重新分配";
        }
        remark += "(" + deviceDto.getStartDevice() + "-" + deviceDto.getEndDevice() + ")" + "给" + agency.getAgencyNo() + "(" + agency.getAlias() + ")";
        if (OperationLogEnum.STATUS_FAIL.getCode().equals(Util.stringConvert(response.getStatus()))) {
            remark += "失败";
        } else {
            remark += "成功";
        }
        logManipulateService.insert(userInfo, deviceDto.toString(), remark, request, response, null, LogManipulateTypeEnum.DEVICE_BIND.getCode());
        return response;
    }


    @PutMapping("/updateDeviceById")
    public ServerResponse updateDeviceById(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (!RoleEnum.SUPER_ADMINISTRATOR.getRoleId().equals(deviceDto.getUserInfo().getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限");
        }
        return deviceService.updateDeviceById(deviceDto);
    }

    @PutMapping("/updateUnbindSum")
    public ServerResponse updateUnbindSum(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (RoleEnum.FINANCE.getRoleId().equals(deviceDto.getUserInfo().getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限修改解绑次数！");
        }
        return deviceService.updateUnbindSum(deviceDto);
    }

    /**
     * 恢复出厂状态
     *
     * @param request
     * @param deviceDto
     * @return
     */
    @PutMapping("/restoreFactoryDefault")
    public ServerResponse restoreFactoryDefault(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (RoleEnum.SUPER_ADMINISTRATOR.getRoleId().compareTo(deviceDto.getUserInfo().getRoleId()) != 0
                && RoleEnum.AGENT.getRoleId().compareTo(deviceDto.getUserInfo().getRoleId()) != 0
        ) {
            return ServerResponse.createByErrorMessage("你没有权限恢复设备状态");
        }
        return deviceService.restoreFactoryDefault(deviceDto);
    }

    @PutMapping("/sendUpdateBoxConfigById")
    public ServerResponse sendUpdateBoxConfigById(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (RoleEnum.FINANCE.getRoleId().equals(deviceDto.getUserInfo().getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限修改设备设置！");
        }
        return deviceService.sendUpdateBoxConfigById(deviceDto);
    }

    @PutMapping("/sendUpdateBoxConfigPulse")
    public ServerResponse sendUpdateBoxConfigPulse(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        return deviceService.sendUpdateBoxConfigPulse(deviceDto);
    }

    @PostMapping("/batchRegisterDevice")
    public ServerResponse batchRegisterDevice(@RequestBody DeviceDto deviceDto, HttpServletRequest request) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        return deviceService.batchRegisterDevice(deviceDto);
    }

    @PostMapping("clearDebugConsumeSum")
    public ServerResponse clearDebugConsumeSum(@RequestBody DeviceDto deviceDto, HttpServletRequest request) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (RoleEnum.FINANCE.getRoleId().equals(deviceDto.getUserInfo().getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限清除调试投币次数！");
        }
        return deviceService.clearDebugConsumeSum(deviceDto);
    }

    @PostMapping("clearFreightLane")
    public ServerResponse clearFreightLane(@RequestBody DeviceDto deviceDto, HttpServletRequest request) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (RoleEnum.FINANCE.getRoleId().equals(deviceDto.getUserInfo().getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限清除货道！");
        }
        return deviceService.clearFreightLane(deviceDto);
    }

    /**
     * 维修替换设备
     */
    @PutMapping("/updateMaintainDevice")
    public ServerResponse updateMaintainDevice(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        UserInfo userInfo = userService.getLoginUserInfo(request);
        deviceDto.setUserInfo(userInfo);
        if (RoleEnum.FINANCE.getRoleId().equals(deviceDto.getUserInfo().getRoleId())) {
            return ServerResponse.createByErrorMessage("你没有权限替换网卡！");
        }
        return deviceService.updateMaintainDevice(deviceDto);
    }



    /**
     * app设置上传日志文件
     *
     * @param file
     * @return
     */
    @PostMapping("/uploadAppFile")
    @ResponseBody
    public ServerResponse uploadAppFile(@RequestParam("file") MultipartFile file) {
        try {
            return deviceService.uploadAppFile(file);
        } catch (Exception e) {
            e.printStackTrace();
            errorLogCommonService.writerInfoException("app设置上传日志文件异常", null, e);
            return ServerResponse.createByErrorMessage(e.getMessage());
        }
    }

    /**
     * 上传app 日志目录
     *
     * @return
     */
    @PostMapping("/retFileInfo")
    public ServerResponse retFileInfo(@RequestBody DeviceDto deviceDto) {
        System.out.println("appFileDtoList:" + deviceDto.getAppFileDtoList());
        redisCacheTemplate.opsForValue().set(RedisKey.DEVICE_APP_FILE_LIST + deviceDto.getDeviceNo(), (Serializable) deviceDto.getAppFileDtoList(), 2, TimeUnit.MINUTES);
        return ServerResponse.createBySuccess();
    }

    /**
     * 查询app 日志文件列表
     *
     * @param request
     * @return
     */
    @PostMapping("/findAppLogDirList")
    public ServerResponse findAppLogDirList(HttpServletRequest request, @RequestBody AppFileDto appFileDto) {
        return deviceService.findAppLogDirList(appFileDto);
    }

    /**
     * 通知app上传日志
     *
     * @param request
     * @return
     */
    @PostMapping("/noticeDownloadFile")
    public ServerResponse noticeDownloadFile(HttpServletRequest request, @RequestBody AppFileDto appFileDto) {
        return deviceService.noticeDownloadFile(appFileDto);
    }

    /**
     * 远程烧号
     *
     * @param request
     * @param remoteWriteDeivceNoDto
     * @return
     */
    @PostMapping("/remoteWriteDeviceNo")
    public ServerResponse remoteWriteDeviceNo(HttpServletRequest request, @RequestBody RemoteWriteDeivceNoDto remoteWriteDeivceNoDto) {
        try {
            UserInfo userInfo = userService.getLoginUserInfo(request);
            if (RoleEnum.SUPER_ADMINISTRATOR.getRoleId().equals(userInfo.getRoleId()) || RoleEnum.AGENT.getRoleId().equals(userInfo.getRoleId())) {
                remoteWriteDeivceNoDto.setUserInfo(userInfo);
                return deviceService.remoteWriteDeviceNo(remoteWriteDeivceNoDto);
            }
            return ServerResponse.createByErrorMessage("你没有权限");

        } catch (Exception e) {
            return ServerResponse.createByErrorMessage(e.getMessage());
        }

    }

    @PostMapping("/vendingParameterSettings")
    public ServerResponse vendingParameterSettings(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        try {
            UserInfo userInfo = userService.getLoginUserInfo(request);
            if (RoleEnum.SUPER_ADMINISTRATOR.getRoleId().equals(userInfo.getRoleId()) || RoleEnum.AGENT.getRoleId().equals(userInfo.getRoleId())) {
                deviceDto.setUserInfo(userInfo);
                return deviceService.vendingParameterSettings(deviceDto);
            }
            return ServerResponse.createByErrorMessage("你没有权限");

        } catch (Exception e) {
            return ServerResponse.createByErrorMessage(e.getMessage());
        }

    }

    @PostMapping("/getConfiguration")
    public ServerResponse getConfiguration(HttpServletRequest request, @RequestBody DeviceDto deviceDto) {
        try {
            UserInfo userInfo = userService.getLoginUserInfo(request);
            if (RoleEnum.SUPER_ADMINISTRATOR.getRoleId().equals(userInfo.getRoleId()) || RoleEnum.AGENT.getRoleId().equals(userInfo.getRoleId())) {
                deviceDto.setUserInfo(userInfo);
                return deviceService.getConfiguration(deviceDto);
            }
            return ServerResponse.createByErrorMessage("你没有权限");

        } catch (Exception e) {
            return ServerResponse.createByErrorMessage(e.getMessage());
        }

    }

    /**
     * 获取售货机设备信息                           <br/>
     * <br/>
     * 需要参数                                  <br/>
     * deviceNo                                 <br/>
     * cpuId                                    <br/>
     * androidMotherboardModel                  <br/>
     * timestamp                                <br/>
     * sign                                     <br/>
     * androidMotherboardModel                  <br/>
     *
     * @param deviceDto
     * @return
     */
    @PostMapping("/findVendmachByCpuId")
    public ServerResponse findVendmachByCpuId(@RequestBody DeviceDto deviceDto) {
        try {
            return ServerResponse.createBySuccess(deviceService.findVendmachByCpuId(deviceDto));
        } catch (Exception e) {
            e.printStackTrace();
            return ServerResponse.createByErrorMessage(e.getMessage());
        }
    }
}
